home *** CD-ROM | disk | FTP | other *** search
/ Deutsche Edition 1 / Deutsche Edition 1.iso / amok / amok_lha / amok77.lha / IFFlib / IFFlib.lha / Examples / GrabScreen.c < prev    next >
C/C++ Source or Header  |  1992-06-14  |  8KB  |  341 lines

  1. /*
  2. **
  3. **    $Id: GrabScreen.c,v 21.2 92/05/18 02:27:41 chris Exp $
  4. **    $Revision: 21.2 $
  5. **
  6. **    $Filename: Examples/GrabScreen.c $
  7. **    $Author: chris $
  8. **    $Release: 21.1 $
  9. **    $Date: 92/05/18 02:27:41 $
  10. **
  11. **    IFF library example program. Compile with Lattice C 5.x.
  12. **    This program saves the contents of the frontmost screen as an IFF file
  13. **    with filename 'RAM:grabscreen.pic'.
  14. **    This example makes use of the IFFL_PushChunk() / IFFL_WriteChunkBytes() /
  15. **    IFFL_PopChunk() functions, it does not use IFFL_SaveBitMap().
  16. **
  17. **    COPYRIGHT (C) 1987-1992 BY CHRISTIAN A. WEBER, BRUGGERWEG 2,
  18. **    CH-8037 ZUERICH, SWITZERLAND.
  19. **    THIS FILE MAY BE FREELY DISTRIBUTED. USE AT YOUR OWN RISK.
  20. **
  21. */
  22.  
  23. #include <proto/exec.h>
  24. #include <exec/memory.h>
  25. #include <proto/graphics.h>
  26. #include <graphics/gfxbase.h>
  27. #include <proto/intuition.h>
  28. #include <intuition/intuitionbase.h>
  29. #include <dos/dos.h>
  30.  
  31. #include <stdio.h>
  32.  
  33. #include <libraries/iff.h>        /* IFF library include file */
  34.  
  35. /*
  36. **    Flags that should be masked out of old 16-bit CAMG before save or use.
  37. **    Note that 32-bit mode id (non-zero high word) bits should not be twiddled
  38. */
  39. #define OLDCAMGMASK  (~(SPRITES|VP_HIDE|GENLOCK_AUDIO|GENLOCK_VIDEO))
  40.  
  41. #define MAXSAVEDEPTH        24
  42. #define BODYBUFSIZE            10000
  43. #define MAXPACKEDSIZE(s)    ((s)*2)
  44.  
  45. /*
  46. **    Masking techniques
  47. */
  48. #define    mskNone                    0
  49. #define    mskHasMask                1
  50. #define    mskHasTransparentColor    2
  51. #define    mskLasso                3
  52.  
  53. /*
  54. **    Compression techniques
  55. */
  56. #define    cmpNone                    0
  57. #define    cmpByteRun1                1
  58.  
  59.  
  60. /****************************************************************************
  61. **    Globals
  62. */
  63.  
  64. struct Library    *IFFBase;
  65. char            version[] = "\0$VER: GrabScreen 21.2 by Christian A. Weber";
  66.  
  67.  
  68. /****************************************************************************
  69. **    This is an example implementation of an IFF writer. It writes the
  70. **    contents of a screen to an IFF ILBM file.
  71. **    Basically, this routine does the same as IFFL_SaveBitMap(), but it is
  72. **    here anyway to show you how to write an IFF file using iff.library's
  73. **    generic write functions.
  74. */
  75.  
  76. BOOL MySaveScreen(struct Screen *screen,char *filename)
  77. {
  78.     IFFL_HANDLE        iff;
  79.     struct BitMap    *bitmap = &screen->BitMap;
  80.     BOOL            result = FALSE;
  81.  
  82.     /*
  83.     **    Open the file for writing
  84.     */
  85.     if(iff = IFFL_OpenIFF(filename,IFFL_MODE_WRITE))
  86.     {
  87.         struct IFFL_BMHD    bmhd;
  88.         ULONG                modeid;
  89.         UBYTE                *colortable;
  90.         int                    count;
  91.  
  92.         /*
  93.         **    Prepare the BMHD structure
  94.         */
  95.         bmhd.w                    = screen->Width;    
  96.         bmhd.h                    = screen->Height;
  97.         bmhd.x                    = screen->LeftEdge;        /* Not very useful :-) */
  98.         bmhd.y                    = screen->TopEdge;
  99.         bmhd.nPlanes            = bitmap->Depth;
  100.         bmhd.masking            = mskNone;
  101.         bmhd.compression        = cmpByteRun1;
  102.         bmhd.pad1                = 0;
  103.         bmhd.transparentColor    = 0;
  104.         bmhd.xAspect            = screen->Width;
  105.         bmhd.yAspect            = screen->Height;
  106.         bmhd.pageWidth            = screen->Width;
  107.         bmhd.pageHeight            = screen->Height;
  108.  
  109.         /*
  110.         **    Create the BMHD chunk. (goto considered useful :-))
  111.         */
  112.         if(IFFL_PushChunk(iff,ID_ILBM,ID_BMHD))
  113.         {
  114.             if(!IFFL_WriteChunkBytes(iff,&bmhd,sizeof(bmhd)))
  115.             {
  116.                 printf("Error writing BMHD data.\n");
  117.                 goto error;
  118.             }
  119.  
  120.             if(!IFFL_PopChunk(iff))
  121.             {
  122.                 printf("Error closing BMHD chunk.\n");
  123.                 goto error;
  124.             }
  125.         }
  126.         else
  127.         {
  128.             printf("Error creating BMHD chunk.\n");
  129.             goto error;
  130.         }
  131.  
  132.         /*
  133.         **    Create the CMAP chunk.
  134.         */
  135.         count = screen->ViewPort.ColorMap->Count;
  136.         if(colortable = AllocMem(count * 3, MEMF_ANY))
  137.         {
  138.             int i;
  139.  
  140.             for(i=0; i<count; ++i)
  141.             {
  142.                 UWORD rgb4 =  GetRGB4(screen->ViewPort.ColorMap,i);
  143.  
  144.                 colortable[i*3+0]  = (rgb4 >> 4) & 0xF0;
  145.                 colortable[i*3+0] |= colortable[i*3+0] >> 4;
  146.  
  147.                 colortable[i*3+1]  = (rgb4     ) & 0xF0;
  148.                 colortable[i*3+1] |= colortable[i*3+1] >> 4;
  149.  
  150.                 colortable[i*3+2]  = (rgb4 << 4) & 0xF0;
  151.                 colortable[i*3+2] |= colortable[i*3+2] >> 4;
  152.             }
  153.  
  154.             if(IFFL_PushChunk(iff,ID_ILBM,ID_CMAP))
  155.             {
  156.                 if(!IFFL_WriteChunkBytes(iff,colortable,count * 3))
  157.                 {
  158.                     printf("Error writing CMAP data.\n");
  159.                     goto error;
  160.                 }
  161.  
  162.                 if(!IFFL_PopChunk(iff))
  163.                 {
  164.                     printf("Error closing CMAP chunk.\n");
  165.                     goto error;
  166.                 }
  167.             }
  168.             else
  169.             {
  170.                 printf("Error creating CMAP chunk.\n");
  171.                 goto error;
  172.             }
  173.  
  174.             FreeMem(colortable,count * 3);
  175.         }
  176.  
  177.         /*
  178.         **    Get the viewport's modes for the CAMG chunk.
  179.         */
  180.         modeid = (GfxBase->LibNode.lib_Version >= 36) ?
  181.             GetVPModeID(&screen->ViewPort) : (screen->ViewPort.Modes&OLDCAMGMASK);
  182.  
  183.         if(IFFL_PushChunk(iff,ID_ILBM,ID_CAMG))
  184.         {
  185.             if(!IFFL_WriteChunkBytes(iff,&modeid,sizeof(modeid)))
  186.             {
  187.                 printf("Error writing CAMG data.\n");
  188.                 goto error;
  189.             }
  190.  
  191.             if(!IFFL_PopChunk(iff))
  192.             {
  193.                 printf("Error closing CAMG chunk.\n");
  194.                 goto error;
  195.             }
  196.         }
  197.         else
  198.         {
  199.             printf("Error creating CAMG chunk.\n");
  200.             goto error;
  201.         }
  202.  
  203.         /*
  204.         **    Generate BODY
  205.         */
  206.         if(IFFL_PushChunk(iff,ID_ILBM,ID_BODY))
  207.         {
  208.             UBYTE    *bodybuf;
  209.  
  210.             if(bodybuf = AllocMem(BODYBUFSIZE,MEMF_ANY))
  211.             {
  212.                 UBYTE    *planes[MAXSAVEDEPTH];
  213.                 int        row,rowbytes,iplane,bodysize=0;
  214.  
  215.                 rowbytes = bitmap->BytesPerRow;
  216.  
  217.                 /*
  218.                 **    Copy the plane pointers into the local array "planes"
  219.                 */
  220.                 for(iplane=0; iplane < bmhd.nPlanes; ++iplane)
  221.                 {
  222.                     planes[iplane] = bitmap->Planes[iplane];
  223.                 }
  224.  
  225.                 for(row=0; row < bmhd.h; ++row)
  226.                 {
  227.                     for(iplane=0; iplane < bmhd.nPlanes; ++iplane)
  228.                     {
  229.                         int comprsize;
  230.  
  231.                         /*
  232.                         **    To speed up things, we collect as much data
  233.                         **    as possible in bodybuf before we write it out.
  234.                         */
  235.                         if(bodysize > (BODYBUFSIZE-MAXPACKEDSIZE(rowbytes)))
  236.                         {
  237.                             if(!IFFL_WriteChunkBytes(iff,bodybuf,bodysize))
  238.                             {
  239.                                 printf("Error writing BODY data.\n");
  240.                                 goto error;
  241.                             }
  242.                             bodysize = 0;
  243.                         }
  244.  
  245.                         /*
  246.                         **    Compress the next row
  247.                         */
  248.                         if(!(comprsize = IFFL_CompressBlock(planes[iplane],
  249.                                 bodybuf+bodysize,rowbytes,IFFL_COMPR_BYTERUN1)))
  250.                         {
  251.                             printf("Error compressing BODY data.\n");
  252.                             goto error;
  253.                         }
  254.                         bodysize        += comprsize;
  255.                         planes[iplane]    += rowbytes;
  256.                     }
  257.                 }
  258.  
  259.                 /*
  260.                 **    Now we're done, so flush the body data buffer
  261.                 */
  262.                 if(bodysize)
  263.                 {
  264.                     if(!IFFL_WriteChunkBytes(iff,bodybuf,bodysize))
  265.                     {
  266.                         printf("Error writing BODY data.\n");
  267.                         goto error;
  268.                     }
  269.                 }
  270.  
  271.                 FreeMem(bodybuf,BODYBUFSIZE);
  272.             }
  273.             else
  274.             {
  275.                 printf("No memory for BODY buffer.\n");
  276.                 goto error;
  277.             }
  278.  
  279.             if(!IFFL_PopChunk(iff))
  280.             {
  281.                 printf("Error closing BODY chunk.\n");
  282.                 goto error;
  283.             }
  284.  
  285.             /*
  286.             **    If we get here, everything was fine.
  287.             */
  288.             result = TRUE;
  289.         }
  290.         else
  291.         {
  292.             printf("Error creating BODY chunk.\n");
  293.             goto error;
  294.         }
  295. error:
  296.         IFFL_CloseIFF(iff);
  297.     }
  298.  
  299.     return result;
  300. }
  301.  
  302. /****************************************************************************
  303. **    Main program
  304. */
  305.  
  306. int main(int argc, char **argv)
  307. {
  308.     int result = RETURN_FAIL;
  309.  
  310.     if(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0))
  311.     {
  312.         if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
  313.         {
  314.             /*
  315.             **    For the new functions we need at least version 21 of iff.library.
  316.             */
  317.             if(IFFBase = OpenLibrary(IFFNAME,21))
  318.             {
  319.                 /*
  320.                 **    Note that we don't lock the screen, so it might go away while
  321.                 **    we're writing its contents to the file, and the picture may
  322.                 **    then contain garbage.
  323.                 */
  324.                 MySaveScreen(IntuitionBase->FirstScreen,"RAM:grabscreen.pic");
  325.                 result = RETURN_OK;
  326.  
  327.                 CloseLibrary(IFFBase);
  328.             }
  329.             else printf("Can't open iff.library V21+\n");
  330.  
  331.             CloseLibrary(IntuitionBase);
  332.         }
  333.         else printf("Can't open intuition.library!\n");
  334.  
  335.         CloseLibrary(GfxBase);
  336.     }
  337.     else printf("Can't open graphics.library!\n");
  338.  
  339.     return result;
  340. }
  341.